// 实现这个项目的构建任务
const { exec } = require('child_process');
const path = require('path');

const { src, dest, parallel, series, watch } = require('gulp');
const loadPlugins = require('gulp-load-plugins');
const plugins = loadPlugins();

const del = require('del');
const browserSync = require('browser-sync');
const bs = browserSync.create();


const program = require('commander');
program.option('-o, --open', 'Open browser on start, Default: `false`')
  .option('-p, --port [type]', 'Specify server port, Default: `2080`')
  .option('-b, --branch [type]', `The name of the branch you'll be pushing to, Default: 'gh-pages'`)
  .option('-prod, --production', 'Production mode flag, Default: `false`')
  .parse(process.argv);

const {
  port = 2080,
  open = false,
  production = false,
  branch = 'gh-pages'
} = program.opts();

const { data } = require('./page.config.js')

/**处理样式文件 */
const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' })
    .pipe(plugins.sass())
    .pipe(dest('temp'))
    .pipe(bs.reload({ stream: true }))
}

/**处理脚本文件 */
const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('temp'))
    .pipe(bs.reload({ stream: true }))
}

/**处理页面文件 */
const page = () => {
  return src('src/*.html', { base: 'src' })
    .pipe(plugins.swig({ data, defaults: { cache: false } }))// 转换html文件，缓存会导致不更新
    .pipe(dest('temp'))
    .pipe(bs.reload({ stream: true }))
}

/**处理图片文件 */
const image = () => {
  return src('src/assets/images/**', { base: 'src' })
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
}

/**处理字体文件 */
const font = () => {
  return src('src/assets/fonts/**', { base: 'src' })
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
}

/**处理公共文件 */
const extra = () => {
  return src('public/**', { base: 'public' })
    .pipe(dest('dist'))
}

/**资源合并并压缩*/
const userefMin = () => {
  return src('temp/*.html', { base: 'temp' })
    .pipe(plugins.useref({ searchPath: ['temp', '.'] }))
    .pipe(plugins.if(/\.js$/, plugins.uglify())) // js压缩
    .pipe(plugins.if(/\.css$/, plugins.cleanCss())) // css压缩
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({
      collapseWhitespace: true,
      minifyCSS: true,
      minifyJS: true
    }))) // html压缩
    .pipe(dest('dist'))
}

/**资源合并*/
const userefOrg = () => {
  return src('temp/*.html', { base: 'temp' })
    .pipe(plugins.useref({ searchPath: ['temp', '.'] }))
    .pipe(dest('dist'))
}

/**启动开发服务器 */
const server = () => {
  watch('src/assets/styles/*.scss', style)
  watch('src/assets/scripts/*.js', script)
  watch('src/*.html', page)

  watch([
    'src/assets/images/**',
    'src/assets/fonts/**',
    'public/**'
  ], bs.reload)

  bs.init({
    notify: false,
    port,
    open,// 是否自动打开浏览器
    // files: 'temp/**',
    server: {
      baseDir: ['temp', 'src', 'public'],// 依次往后读取文件
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

/**检查js规范 */
const lintJs = () => {
  return src('src/assets/scripts/*.js')
    .pipe(plugins.eslint({
      configFile: 'eslintconfig.json'
    }))
    .pipe(plugins.eslint.format())
}

/**检查sass规范 */
const lintSass = () => {
  return src('src/assets/styles/*.s+(a|c)ss', { base: 'src' })
    .pipe(plugins.sassLint())
    .pipe(plugins.sassLint.format())
}



/**删除文件 */
const clean = () => {
  return del(['dist', 'temp'])
}

/**组合任务 */
const compile = parallel(style, script, page)

/**构建任务 */
const build = series(clean, parallel(series(compile, production ? userefMin : userefOrg), image, font, extra));

/**开发任务 */
const serve = series(compile, server)

/**检验js,sass */
const lint = parallel(lintJs, lintSass);

/**启动生产服务器 */
const start = () => {
  bs.init({
    notify: false,
    port,
    open,// 是否自动打开浏览器
    files: 'dist/**',
    server: {
      baseDir: ['dist'],// 依次往后读取文件
    }
  })
}

/**github提交 */
const gitShell = `git init && git add . && git commit -m 'commit to ${branch ? branch : 'master'}' &&  git remote add origin git@github.com:BoreyLee/BoreyLee.github.io.git && git fetch ${branch ? `&& git checkout -b ${branch}` : ''} && git push --set-upstream origin ${branch ? `${branch}:${branch}` : 'master'} -f`
const gitUpload = (cb) => {
  exec(gitShell, { cwd: path.resolve(__dirname, './dist') }, (error, stdout, stderr) => {
    console.log(error, stdout, stderr);
    cb()
  })
}

/**代码部署 */
const deploy = series(gitUpload);

module.exports = {
  compile,
  clean,
  lint,
  build,
  serve,
  start,
  deploy,
}